namespace ResumableDownload
{
    using System.Collections.Generic;
    using System.Reflection;
    using System.Windows;
    using Funq;
    using GalaSoft.MvvmLight.Messaging;
    using ViewModel;
    using WP7Contrib.Communications;
    using WP7Contrib.Logging;
    using WP7Contrib.Messaging;
    using WP7Contrib.Serialization.Helpers;
    using WP7Contrib.Services.DownloadManager;
    using WP7Contrib.Services.Navigation;
    using WP7Contrib.Services.Settings;
    using WP7Contrib.Services.Storage;

    public class BootStrapper
    {
        #region Constants and Fields

        #endregion

        #region Constructors and Destructors

        public BootStrapper()
        {
            this.Container = new Container();

            this.ConfigureContainer();
        }

        #endregion

        #region Properties

        public Container Container { get; private set; }

        #endregion

        #region Implemented Interfaces

        #region IDisposable

        public void Dispose()
        {
            if (this.Container != null)
            {
                this.Container.Dispose();
                this.Container = null;
            }
        }

        #endregion

        #endregion

        #region Methods

        private void ConfigureContainer()
        {
            this.Container.Register<ILog>(c => new DebugLog()).ReusedWithin(ReuseScope.Container);

            this.Container.Register<IStoreSettings>(c => new SettingsStore(this.Container.Resolve<ILog>()));
            this.Container.Register<ISettings>(c => new Settings(new List<NetworkType> { NetworkType.Ethernet, NetworkType.Wireless}));
            
            var serialisationAssemblies = new List<Assembly> { this.GetType().Assembly, typeof(SerializeUri).Assembly };
            this.Container.Register<IStorageService>(c => new StorageService(serialisationAssemblies, c.Resolve<ILog>()));

            this.Container.Register<INetworkService>(c => new NetworkMonitor(500));

            this.Container.Register<IDownloadService>(c => new ResumableFileDownloader(c.Resolve<ISettings>(),
                                                                                       c.Resolve<IStorageService>(),
                                                                                       c.Resolve<INetworkService>(),
                                                                                       c.Resolve<ILog>())).ReusedWithin(ReuseScope.Container);

            this.Container.Register<IMessenger>(c => new LastMessageReplayMessenger());

            this.Container.Register<INavigationService>(c => new ApplicationFrameNavigationService(((App)Application.Current).RootFrame));

            this.Container.Register(
                c =>
                new MainViewModel(
                    c.Resolve<IDownloadService>(),
                    c.Resolve<INetworkService>(),
                    c.Resolve<INavigationService>(),
                    c.Resolve<IMessenger>(),
                    c.Resolve<ILog>()));

            this.Container.Register(
                c =>
                new ImageViewModel(
                    c.Resolve<INavigationService>(),
                    c.Resolve<IMessenger>(),
                    c.Resolve<ILog>()));

            this.Container.Register(
                c =>
                new Mp3ViewModel(
                    c.Resolve<INavigationService>(),
                    c.Resolve<IMessenger>(),
                    c.Resolve<ILog>()));
        }

        #endregion
    }
}